﻿/*========================== 
 * @author 郑金泉
 * @desc Model配置信息类
 * ========================= */
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using Obsidian.Utils;

namespace Obsidian.Config
{
    public class ModelConfig
    {

        private static Hashtable htDb = Hashtable.Synchronized(new Hashtable());

        public static ModelPackageInfo GetModelPackageInfo(string dbAlias, string tableAlias)
        {
            ModelPackageInfo mp;
            if (!htDb.ContainsKey(dbAlias))
            {
                mp = new ModelPackageInfo(dbAlias);
                htDb.Add(dbAlias, mp);
            }
            else
            {
                mp = (ModelPackageInfo)htDb[dbAlias];
            }
            return mp;
        }

        public class ModelInfo
        {
            
            private string alias;
            private string type;

            public string Alias
            {
                get { return this.alias; }
            }

            internal void SetAlias(string val)
            {
                this.alias = val;
            }

            public string Type
            {
                get { return this.type; }
            }

            internal void SetType(string val)
            {
                this.type = val;
            }

        }

        public class ModelPackageInfo
        {
            private DateTime modified = DateTime.MinValue;
            private string dbAlias;
            private string assemblyFile;
            private List<ModelInfo> listModel = new List<ModelInfo>();
            private Hashtable htModel = Hashtable.Synchronized(new Hashtable());

            public ModelPackageInfo(string dbAlias)
            {
                this.dbAlias = dbAlias;
            }

            public string DbAlias
            {
                get { return dbAlias; }
            }

            public string AssemblyFile
            {
                get { return assemblyFile; }
            }

            public DateTime Modified
            {
                get { return this.modified; }
            }

            public List<ModelInfo> ModelInfos
            {
                get { return listModel; }
            }

            public ModelInfo GetModeInfo(string alias)
            {
                if (htModel.ContainsKey(alias))
                    return (ModelInfo)htModel[alias];
                else
                    return null;
            }

            public bool CheckForChanged()
            {
                string configFile = RuntimeUtil.BinPath + "\\model_config\\" + this.dbAlias + ".xml";

                if (!this.modified.Equals(DateTime.MinValue) && !File.Exists(configFile))
                {
                    this.assemblyFile = null;
                    listModel.Clear();
                    htModel.Clear();
                    this.modified = DateTime.MinValue;
                    return true;
                }

                FileInfo file = new FileInfo(configFile);
                if (this.modified.Equals(file.LastWriteTime))
                    return false;

                lock (htModel)
                {
                    listModel.Clear();
                    htModel.Clear();

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(configFile);

                    string val;
                    XmlNode node = xmlDoc.SelectSingleNode("modelPackage");
                    if (!XmlUtil.TryGetAttrValue(node, "assemblyFile", out val) || String.IsNullOrEmpty(val))
                        throw new Exception("assemblyFile属性不能为空!");
                    this.assemblyFile = AppConfig.FullPath(val);

                    XmlNodeList nodeList = xmlDoc.SelectNodes("modelPackage/models/model");
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        ModelInfo info = new ModelInfo();
                        node = nodeList.Item(i);

                        if (!XmlUtil.TryGetAttrValue(node, "alias", out val) || String.IsNullOrEmpty(val))
                            throw new Exception("alias属性不能为空!");
                        info.SetAlias(val);

                        if (!XmlUtil.TryGetAttrValue(node, "type", out val) || String.IsNullOrEmpty(val))
                            throw new Exception("type属性不能为空!");
                        info.SetType(val);

                        if (htModel.ContainsKey(info.Alias))
                            throw new Exception("存在重复别名：" + info.Alias);

                        listModel.Add(info);
                        htModel.Add(info.Alias, info);

                    }

                    this.modified = file.LastWriteTime;
                }

                return true;
            }
        }

    }
}
